package com.zhangdi.dwperms.service.impl;

import com.zhangdi.dwperms.commons.utils.SpringUtils;
import com.zhangdi.dwperms.service.MenuService;
import com.zhangdi.dwperms.entity.Menu;
import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Service
public class ShiroService {
    private static final Logger log = LoggerFactory.getLogger(ShiroService.class);

    private final MenuService menuService;

//    @Lazy
    public ShiroService(MenuService menuService) {
        this.menuService = menuService;
    }

    /**
     * 获得租户下所有权限，没有则 db - redis
     * 修改权限时要处理缓存，否则出现不一致情况
     * TODO 暂定这样，如果有问题，做出修改后直接从数据库取
     *
     * @param code
     * @return
     */
    public Map<String, String> getFromCache(String code) {
        Map<String, String> menuMap = new LinkedHashMap<>();
        List<Menu> tenantMenuList = null;
//        if (tenantCode.equals("sys")) {
            tenantMenuList = menuService.findDefaultUserPermissions();
//        } else {
//            tenantMenuList = menuService.findPermissionsByTenantCode(tenantCode);
//        }

        if (null != tenantMenuList && tenantMenuList.size() > 0) {
            for (Menu menu : tenantMenuList) {
                if (null == menu) {
                    continue;
                }
                menuMap.put(menu.getUrl(), menu.getPerms());
            }
        }

        return regUrlPerms(menuMap);
    }

    private Map<String, String> regUrlPerms(Map<String, String> menus) {
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();

        // 系统默认过滤器
        filterChainDefinitionMap.put("/", "anon");
        filterChainDefinitionMap.put("/rest/**", "anon");
        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/register", "anon");
        filterChainDefinitionMap.put("/403", "anon");
        filterChainDefinitionMap.put("/404", "anon");
        filterChainDefinitionMap.put("/500", "anon");
        filterChainDefinitionMap.put("/error", "anon");

        Iterator<Map.Entry<String, String>> iterator = menus.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, String> entry = iterator.next();
            filterChainDefinitionMap.put(entry.getKey(), "authc,perms[" + entry.getValue() + "]");
        }

//        filterChainDefinitionMap.put("/**", "authc");

        return filterChainDefinitionMap;
    }

    /**
     * 更新 权限 后台管理 过滤器链
     */
    public void updateDefaultFilterChain(String tenantCode) {
        AbstractShiroFilter shiroFilter = SpringUtils.getBean(AbstractShiroFilter.class);

        PathMatchingFilterChainResolver filterChainResolver = (PathMatchingFilterChainResolver) shiroFilter
                .getFilterChainResolver();
        DefaultFilterChainManager filterChainManager = (DefaultFilterChainManager) filterChainResolver
                .getFilterChainManager();

        //TODO URL = /企业简称/接口地址 选择性清除
        //TODO 清除默认权限，重新注册/permission
        //manager.getFilterChains()
        //TODO 1.从缓存中取出 默认权限集合

        filterChainManager.getFilterChains().clear();
        // 重新构建生成
        Map<String, String> filterChainDefinitionMap = getFromCache("sys");
        for (Map.Entry<String, String> entry : filterChainDefinitionMap.entrySet()) {
            String url = entry.getKey();
            String chainDefinition = entry.getValue().trim()
                    .replace(" ", "");
            filterChainManager.createChain(url, chainDefinition);
        }
        log.info("更新 Shiro 过滤器链");
    }

//    public void updateDefaultFilterChain111(String url) {
//        synchronized (shiroFilterFactoryBean) {
//            AbstractShiroFilter shiroFilter;
//            try {
//                shiroFilter = (AbstractShiroFilter) shiroFilterFactoryBean
//                        .getObject();
//            } catch (Exception e) {
//                throw new ShiroException(
//                        "get ShiroFilter from restShiroFilterFactoryBean error!");
//            }
//            PathMatchingFilterChainResolver filterChainResolver = (PathMatchingFilterChainResolver) shiroFilter
//                    .getFilterChainResolver();
//            DefaultFilterChainManager manager = (DefaultFilterChainManager) filterChainResolver
//                    .getFilterChainManager();
//
//            manager.getFilterChains().remove("/**");
//            shiroFilterFactoryBean.getFilterChainDefinitionMap().remove("/**");
//
//            shiroFilterFactoryBean.getFilterChainDefinitionMap().put(url, "perms[test333]");
//            manager.createChain(url, "perms[test333]");
//
//            shiroFilterFactoryBean.getFilterChainDefinitionMap().put("/**", "authc");
//            manager.createChain("/**", "authc");
//
////            manager.addToChain(url, "perms", "test333");
//
//            log.info("更新 Shiro 过滤器链111");
//        }
//    }
}